home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $Id: BTXService.cpp 1.3 1995/09/26 16:48:58 olsen Exp olsen $
- **
- ** :ts=4
- */
-
- /*
- * Amiga changes copyright © 1995 by Olaf Barthel, All Rights Reserved
- *
- * Copyright (c) 1992, 1993 Arno Augustin, Frank Hoering, University of
- * Erlangen-Nuremberg, Germany.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * Erlangen-Nuremberg, Germany.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This software has not been validated by the ``Bundesamt fuer Zulassungen in
- * der Telekommunikation'' of the ``Deutsche Bundepost Telekom'' and thus
- * must not be used for accessing the BTX-Network of the Telekom in Germany.
- *
- * Diese Software hat keine Zulassung durch das Bundesamt fuer Zulassungen in
- * der Telekommunikation der Deutschen Bundespost Telekom und darf daher nicht
- * am Netz der Deutschen Bundespost Telekom in Deutschland betrieben werden.
- */
-
- #define USE_PROTOCOL
-
- #include "BTXService.hpp"
- #include <string.h>
- #include <ctype.h>
- #include <stdio.h>
-
- #define LOG(x) log()
- #define ERRLOG(x) errlog()
-
- /******************************************************************************/
-
- BTXService::~BTXService()
- {
- Close();
- }
-
- BTXService::BTXService()
- {
- memset(screen,0,sizeof(screen));
- memset(&t,0,sizeof(t));
- memset(&backup,0,sizeof(backup));
- memset(data,0,sizeof(data));
-
- rows = fontheight = reachedEOF = 0;
- pushback = -1;
-
- telefile = NULL;
- teledownload = FALSE;
- telename[0] = 0;
- telemode = MODE_Unknown;
-
- #ifdef USE_PROTOCOL
- protocolfile = NULL;
- #endif
- }
-
- VOID BTXService::Close(VOID)
- {
- if(telefile)
- {
- fclose(telefile);
-
- telefile = NULL;
- }
-
- #ifdef USE_PROTOCOL
- if(protocolfile)
- {
- fclose(protocolfile);
- protocolfile = NULL;
- }
- #endif
- }
-
- LONG BTXService::Open(BTXDisplay *Disp,Application *Appl)
- {
- AppDisplay = Disp;
- App = Appl;
-
- Disp->MonitorData(&rows,&fontheight);
-
- #ifdef USE_PROTOCOL
- protocolfile = fopen("t:protocol","wb");
- #endif
-
- init_layer6();
- return(0);
- }
-
- int BTXService::ProcessInput(VOID)
- {
- return(process_BTX_data());
- }
-
- UBYTE BTXService::ConvertChar(int c,int s,int d)
- {
- static UBYTE supp_map[96] =
- { ' ', 0xa1, 0xa2, 0xa3, '$', 0xa5, '#', 0xa7, 0xa4, '`', '\"', 0xab,
- 0, 0, 0, 0, 0xb0, 0xb1, 0xb2, 0xb3, 0xd7, 0xb5, 0xb6, 0xb7, 0xf7,
- '\'', '\"', 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0, 0x60, 0x27, 0, '~',
- 0xaf, 0, 0, 0x22, 0x22, 0xb0, 0, 0, 0x22, 0xb8, 0, 0xad, 0xb9, 0xae,
- 0xa9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc6, 0, 0, 0, 0, 0,
- 0, 0, 0xd8, 0, 0, 0xfe, 0, 0, 0, 0, 0xe6, 0, 0, 0, 0, 0, 0, 0, 0xf8,
- 0, 0xdf, 0xde, 0, 0, 0 };
-
- static UBYTE diacritical_map[26*2][16] = {
- { 0, 0xc0, 0xc1, 0xc2, 0xc3, 0, 0, 0, 0xc4, 0xc4, 0xc5, 0, 0, 0xc4, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* B */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc7, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* D */
- { 0, 0xc8, 0xc9, 0xca, 0, 0, 0, 0, 0xcb, 0xcb, 0, 0, 0, 0xcb, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* H */
- { 0, 0xcc, 0xcd, 0xce, 0, 0, 0, 0, 0xcf, 0xcf, 0, 0, 0, 0xcf, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0xd1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* N */
- { 0, 0xd2, 0xd3, 0xd4, 0xd5, 0, 0, 0, 0xd6, 0xd6, 0, 0, 0, 0xd6, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* T */
- { 0, 0xd9, 0xda, 0xdb, 0, 0, 0, 0, 0xdc, 0xdc, 0, 0, 0, 0xdc, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* X */
- { 0, 0, 0xdd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0xe0, 0xe1, 0xe2, 0xe3, 0, 0, 0, 0xe4, 0xe4, 0xe5, 0, 0, 0xe4, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xe7, 0, 0, 0, 0 }, /* c */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0xe8, 0xe9, 0xea, 0, 0, 0, 0, 0xeb, 0xeb, 0, 0, 0, 0xeb, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* h */
- { 0, 0xec, 0xed, 0xee, 0, 0, 0, 0, 0xef, 0xef, 0, 0, 0, 0xef, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0xf1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* n */
- { 0, 0xf2, 0xf3, 0xf4, 0xf5, 0, 0, 0, 0xf6, 0xf6, 0, 0, 0, 0xf6, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* t */
- { 0, 0xf9, 0xfa, 0xfb, 0, 0, 0, 0, 0xfc, 0xfc, 0, 0, 0, 0xfc, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0xfd, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0xff, 0, 0 }, /* y */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
-
- UBYTE Char;
-
- /* ASCII out of 1st supplementary set of mosaic characters */
- if(s==SUP1 && c>=0x40 && c<=0x5f)
- Char = (UBYTE)c;
- else
- Char = (UBYTE)' ';
-
- /* supplementary set of graphic characters */
- if(s==SUPP && supp_map[c-0x20])
- Char = (UBYTE)supp_map[c-0x20];
- else
- {
- /* composed characters, diacritical marks (page 123) */
- if(s==PRIM)
- {
- if(!d)
- Char = (UBYTE)c; /* ASCII character */
- else
- {
- if(d>=0x40 && d<=0x4f)
- {
- if(c>=0x41 && c<=0x5a && diacritical_map[c-0x41][d&0xf])
- Char = (UBYTE)diacritical_map[c-0x41][d&0xf];
- else
- {
- if(c>=0x61 && c<=0x7a && diacritical_map[c-0x61+26][d&0xf])
- Char = (UBYTE)diacritical_map[c-0x61+26][d&0xf];
- }
- }
- }
- }
- }
-
- return(Char);
- }
-
- VOID BTXService::GetMatrix(UBYTE *Matrix,int *CursorX,int *CursorY)
- {
- if(Matrix)
- {
- int x,y;
-
- memset(Matrix,' ',40 * 24);
-
- for(y = 0 ; y < rows ; y++)
- {
- for(x = 0 ; x < 40 ; x++)
- Matrix[y * 40 + x] = ConvertChar(screen[y][x].chr & 0x7f,screen[y][x].set,(screen[y][x].chr>>8) & 0x7f);
- }
- }
-
- if(CursorX)
- {
- if(t.cursor_on)
- *CursorX = t.cursorx;
- else
- *CursorX = -1;
- }
-
- if(CursorY)
- {
- if(t.cursor_on)
- *CursorY = t.cursory;
- else
- *CursorY = -1;
- }
- }
-
- /******************************************************************************/
-
- /* all 'page' references refer to 'FTZ 157 D2 E' */
-
- #include "Control.h"
- #include "Font.h"
- #include "Attributes.h"
-
- /*
- * initialize layer6 variables
- */
- void BTXService::init_layer6()
- {
- int y;
-
- fontheight = 10;
- rows = 24;
- t.cursorx = t.cursory = 1;
- t.wrap = 1;
- t.service_break = 0;
- t.scroll_area = 0;
- t.scroll_impl = 1;
- t.cursor_on = 0;
- t.par_attr = 0;
- t.par_fg = WHITE;
- t.par_bg = TRANSPARENT;
- for(y=0; y<24; y++) AppDisplay->define_fullrow_bg(y, BLACK);
- clearscreen();
- default_sets();
- }
-
- /*
- * Read and process one layer6 code sequence.
- * Returns 1 when DCT (terminate data collect 0x1a) is received, else 0.
- */
-
- int BTXService::process_BTX_data()
- {
- int set, c1, c2, dct=0;
-
- c1 = layer2getc();
-
- if(c1>=0x00 && c1<=0x1f)
- dct = primary_control_C0(c1);
- else
- {
- if(c1>=0x80 && c1<=0x9f)
- supplementary_control_C1(c1, 0);
- else
- {
- if(t.sshift)
- set = t.G0123L[ t.sshift ];
- else
- set = t.G0123L[ t.leftright[ (c1&0x80) >> 7 ] ];
-
- if( set == SUPP && (c1 & 0x70) == 0x40 ) /* diacritical ??? */
- {
- LOG(("diacritical mark %d\n", c1 & 0x0f));
-
- c2 = layer2getc();
-
- if(c2&0x60)
- c1 = (c1<<8) | c2;
-
- t.sshift = 0;
- }
-
- LOG(("OUTPUT 0x%02x '%c'\n", c1&0xff, isprint(c1&0xff) ? c1&0xff : '.'));
-
- output(c1);
-
- t.lastchar = c1;
- }
- }
-
- return dct;
- }
-
-
- /*
- * get one byte from protocol layer 2.
- */
-
- int BTXService::layer2getc()
- {
- LONG Value;
- UBYTE c;
-
- /* is there a pushed back character ? */
- if(pushback >= 0)
- {
- Value = App->DispatchDisplayEvent();
-
- if(Value == CHANNELERR_EOF)
- reachedEOF = 1;
-
- c = (UBYTE)pushback;
- pushback = -1;
- }
- else
- {
- while(!reachedEOF)
- {
- Value = App->DispatchEvent();
-
- switch(Value)
- {
- case CHANNELERR_EOF:
-
- reachedEOF = 1;
- return(US);
-
- case CHANNELERR_Timeout:
- case CHANNELERR_Nothing:
-
- App->WaitEvent();
- continue;
- }
-
- if(Value < 0)
- reachedEOF = 1;
- else
- {
- c = (UBYTE)Value;
-
- #ifdef USE_PROTOCOL
- if(protocolfile)
- fputc(c,protocolfile);
- #endif
- }
-
- break;
- }
-
- if(reachedEOF)
- c = US;
- }
-
- if(reachedEOF)
- App->EventExit();
-
- LOG(("(%c %03x %2d/%2d %2x/%2x) (0x%02x) ", t.serialmode ? 'S' : 'P',
- t.serialmode ? screen[t.cursory-1][t.cursorx-1].attr : t.par_attr,
- t.cursory, t.cursorx,
- t.serialmode ? screen[t.cursory-1][t.cursorx-1].fg : t.par_fg,
- t.serialmode ? screen[t.cursory-1][t.cursorx-1].bg : t.par_bg, c));
-
- return c;
- }
-
-
- /*
- * unget character 'c'. Only one character of pushback is possible !
- */
- void BTXService::layer2ungetc(int c)
- {
- if(pushback < 0)
- {
- pushback = c;
- LOG(("<-- character pushed back\n"));
- }
- else
- ERRLOG(("XBTX: internal error: ungetc-buffer overflow !\n"));
- }
-
-
- /*
- * initialize default character sets (page 113)
- */
- void BTXService::default_sets()
- {
- t.G0123L[G0] = PRIM;
- t.G0123L[G1] = SUP2;
- t.G0123L[G2] = SUPP;
- t.G0123L[G3] = SUP3;
- t.G0123L[ L] = L; /* always L !!! (cannot be changed) */
- t.leftright[0] = G0;
- t.leftright[1] = G2;
- t.sshift = 0;
- t.save_left = G0;
- t.prim = G0;
- t.supp = G2;
- }
-
- /*
- * move the cursor, perform automatic wraparound (page 97)
- * and implicite scrolling (page 101)
- */
- void BTXService::move_cursor(int cmd, int y, int x)
- {
- int up=0, down=0;
-
- /* erase old cursor */
- if(t.cursor_on) AppDisplay->xcursor(t.cursorx-1, t.cursory-1);
-
- /* move & wrap */
- switch(cmd) {
- case APF:
- if(++t.cursorx > 40)
- if(t.wrap) { t.cursorx-=40; down=1; }
- else t.cursorx=40;
- break;
-
- case APB:
- if(--t.cursorx < 1)
- if(t.wrap) { t.cursorx+=40; up=1; }
- else t.cursorx=1;
- break;
-
- case APU: up=1; break;
- case APD: down=1; break;
- case APR: t.cursorx=1; break;
-
- case APA:
- t.hold_mosaic = 0;
- if(t.wrap) { /* wrap !! (SKY-NET *200070000000004a#) */
- if(x < 1) { x += 40; y--; }
- if(x > 40) { x -= 40; y++; }
- if(y < 1) y += rows;
- if(y > rows) y -= rows;
- }
- else {
- if(x < 1) x = 1;
- if(x > 40) x = 40;
- if(y < 1) y = 1;
- if(y > rows) y = rows;
- }
-
- t.cursorx=x;
- t.cursory=y;
- break;
- }
-
- if(up) {
- t.hold_mosaic = 0;
- if(t.scroll_area && t.scroll_impl &&
- t.cursory == t.scroll_upper) scroll(0);
- else
- if(--t.cursory < 1)
- if(t.wrap) t.cursory += rows;
- else t.cursory = 1;
- }
-
- if(down) {
- t.hold_mosaic = 0;
- if(t.scroll_area && t.scroll_impl &&
- t.cursory == t.scroll_lower) scroll(1);
- else
- if(++t.cursory > rows)
- if(t.wrap) t.cursory -= rows;
- else t.cursory = rows;
- }
-
- /* draw new cursor */
- if(t.cursor_on) AppDisplay->xcursor(t.cursorx-1, t.cursory-1);
- }
-
-
- /*
- * process a code from the primary control set C0 (0x00 - 0x1f).
- * Returns 1 when DCT is received, else 0.
- */
-
- int BTXService::primary_control_C0(int c1) /* page 118, annex 6 */
- {
- int c2, x, y;
-
- switch(c1) {
-
- case APB:
- LOG(("APB active position back\n"));
- move_cursor(APB);
- break;
-
- case APF:
- LOG(("APF active position forward\n"));
- move_cursor(APF);
- break;
-
- case APD:
- LOG(("APD active position down\n"));
- move_cursor(APD);
- break;
-
- case APU:
- LOG(("APU active position up\n"));
- move_cursor(APU);
- break;
-
- case CS:
- LOG(("CS clear screen\n"));
- t.leftright[0] = t.save_left;
- clearscreen();
- break;
-
- case APR:
- LOG(("APR active position return\n"));
- move_cursor(APR);
- break;
-
- case LS1:
- case LS0:
- c2 = (c1==LS1) ? 1 : 0;
- LOG(("LS%d locking shift G%d left\n", c2, c2));
- t.leftright[0] = c2; /* G0 or G1 !! */
- t.save_left = c2;
- break;
-
- case CON:
- LOG(("CON cursor on\n"));
- if(!t.cursor_on) {
- t.cursor_on = 1;
- AppDisplay->xcursor(t.cursorx-1, t.cursory-1);
- }
- break;
-
- case RPT:
- LOG(("RPT repeat last char\n"));
- c2 = layer2getc() & 0x3f;
- LOG((" %d times\n", c2));
- while(c2--) output(t.lastchar);
- break;
-
- case COF:
- LOG(("COF cursor off\n"));
- if(t.cursor_on) {
- t.cursor_on = 0;
- AppDisplay->xcursor(t.cursorx-1, t.cursory-1);
- }
- break;
-
- case CAN:
- LOG(("CAN cancel\n"));
- y = t.cursory-1;
- screen[y][t.cursorx-1].chr = ' ';
- screen[y][t.cursorx-1].set = PRIM;
- for(x=t.cursorx; x<40; x++) { /* clear to the right */
- screen[y][x].chr = ' ';
- screen[y][x].set = PRIM;
- screen[y][x].mark = 0;
- screen[y][x].attr = screen[y][t.cursorx-1].attr;
- screen[y][x].fg = screen[y][t.cursorx-1].fg;
- screen[y][x].bg = screen[y][t.cursorx-1].bg;
- }
- for(x=t.cursorx-1; x<40; x++) redrawc(x+1, y+1);
- break;
-
- case SS2:
- LOG(("SS2 single shift G2 left\n"));
- t.sshift = G2;
- break;
-
- case ESC:
- LOG(("ESC escape sequence\n"));
- do_ESC();
- break;
-
- case SS3:
- LOG(("SS3 single shift G3 left\n"));
- t.sshift = G3;
- break;
-
- case APH:
- LOG(("APH active position home\n"));
- move_cursor(APA, 1, 1);
- t.par_attr = 0;
- t.par_fg = WHITE;
- t.par_bg = TRANSPARENT;
- break;
-
- case US:
- LOG(("US unit separator (or APA)\n"));
- do_US();
- break;
-
- default:
- LOG(("??? unprocessed control character 0x%02x - ignored\n", c1));
- if(c1 == DCT) return 1;
- }
-
- return 0;
- }
-
-
- /*
- * process a code from the supplementary control set C1 (0x80 - 0x9f).
- * 'fullrow' indicates attribute application to the complete row.
- * Most codes advance active cursor position by one !
- */
-
- void BTXService::supplementary_control_C1(int c1, int fullrow) /* page 121, annex 6 */
- {
- int adv, mode = fullrow ? 2 : t.serialmode;
-
- switch(c1) {
- /* serial parallel */
- case 0x80: /* ABK BKF */
- case 0x81: /* ANR RDF */
- case 0x82: /* ANG GRF */
- case 0x83: /* ANY YLF */
- case 0x84: /* ANB BLF */
- case 0x85: /* ANM MGF */
- case 0x86: /* ANC CNF */
- case 0x87: /* ANW WHF */
- LOG(("set foreground to color #%d %s\n", t.clut*8+c1-0x80,
- (mode==1) ? "(+ unload L set)" : ""));
- set_attr(ATTR_FOREGROUND, 1, t.clut*8+c1-0x80, mode);
- if(mode==1) {
- t.leftright[0] = t.save_left;
- }
- break;
-
- case FSH:
- LOG(("FSH flashing begin\n"));
- /* set_attr(ATTR_FLASH, 1, 0, mode); */
- break;
-
- case STD:
- LOG(("STD flashing steady\n"));
- /* set_attr(ATTR_FLASH, 0, 0, mode); */
- break;
-
- case EBX:
- LOG(("EBX end of window\n"));
- /* set_attr(ATTR_WINDOW, 0, 0, mode); */
- break;
-
- case SBX:
- LOG(("SBX start of window\n"));
- /* set_attr(ATTR_WINDOW, 1, 0, mode); */
- break;
-
- case NSZ:
- LOG(("NSZ normal size\n"));
- set_attr(ATTR_NODOUBLE, 1, 0, mode);
- break;
-
- case DBH:
- LOG(("DBH double height\n"));
- set_attr(ATTR_YDOUBLE, 1, 0, mode);
- break;
-
- case DBW:
- LOG(("DBW double width\n"));
- set_attr(ATTR_XDOUBLE, 1, 0, mode);
- break;
-
- case DBS:
- LOG(("DBS double size\n"));
- set_attr(ATTR_XYDOUBLE, 1, 0, mode);
- break;
-
- /* serial parallel */
- case 0x90: /* MBK BKB */
- case 0x91: /* MSR RDB */
- case 0x92: /* MSG GRB */
- case 0x93: /* MSY YLB */
- case 0x94: /* MSB BLB */
- case 0x95: /* MSM MGB */
- case 0x96: /* MSC CNB */
- case 0x97: /* MSW WHB */
- /* at fullrow control the parallel set is used ! */
- LOG(("set %s to color #%d\n", (mode==1) ?
- "mosaic foreground (+ invoke L set)" : "background",
- t.clut*8+c1-0x90));
- if(mode==1) {
- set_attr(ATTR_FOREGROUND, 1, t.clut*8+c1-0x90, 1);
- t.save_left = t.leftright[0];
- t.leftright[0] = L;
- }
- else set_attr(ATTR_BACKGROUND, 1, t.clut*8+c1-0x90, mode);
- break;
-
- case CDY:
- LOG(("CDY conceal display\n"));
- set_attr(ATTR_CONCEALED, 1, 0, mode);
- break;
-
- case SPL:
- LOG(("SPL stop lining\n"));
- set_attr(ATTR_UNDERLINE, 0, 0, mode);
- break;
-
- case STL:
- LOG(("STL start lining\n"));
- set_attr(ATTR_UNDERLINE, 1, 0, mode);
- break;
-
- case CSI:
- LOG(("CSI control sequence introducer\n"));
- adv = do_CSI();
- break;
-
- case 0x9c:
- if(mode==1) {
- LOG(("BBD black background\n"));
- set_attr(ATTR_BACKGROUND, 1, t.clut*8+BLACK, 1);
- } else {
- LOG(("NPO normal polarity\n"));
- set_attr(ATTR_INVERTED, 0, 0, mode);
- }
- break;
-
- case 0x9d:
- if(mode==1) {
- LOG(("NBD new background\n"));
- set_attr(ATTR_BACKGROUND, 1,
- screen[t.cursory-1][t.cursorx-1].fg, 1);
- } else {
- LOG(("IPO inverted polarity\n"));
- set_attr(ATTR_INVERTED, 1, 0, mode);
- }
- break;
-
- case 0x9e:
- if(mode==1) {
- LOG(("HMS hold mosaic\n"));
- t.hold_mosaic = 1;
- } else {
- LOG(("TRB transparent background\n"));
- set_attr(ATTR_BACKGROUND, 1, TRANSPARENT, mode);
- }
- break;
-
- case 0x9f:
- if(mode==1) {
- LOG(("RMS release mosaic\n"));
- t.hold_mosaic = 0;
- } else {
- LOG(("STC stop conceal\n"));
- set_attr(ATTR_CONCEALED, 0, 0, mode);
- }
- break;
- }
-
- /* serial attribute controls advance cursor 1 char forwards ! (page 90) */
- if(mode==1 && (c1!=CSI || adv) )
- if(t.hold_mosaic) output(t.lastchar); /* HMS/RMS (page 96) */
- else move_cursor(APF);
- }
-
-
- void BTXService::do_US() /* page 85/86 */
- {
- static UBYTE TFI_string[] = { SOH, US, 0x20, 0x7f, 0x40, ETB };
- int c2, c3, alphamosaic = 0;;
-
- /* implicite return from service break !!! (any US sequence !?!) */
- if(t.service_break) {
- t = backup;
- move_cursor(APA, t.cursory, t.cursorx);
- }
-
- for(;;)
- {
- c2 = layer2getc();
- if(c2 != 0x1f)
- break;
- }
-
- switch(c2) {
- case 0x20: /* annex 7.3 */
- LOG((" TFI Terminal Facility Identifier\n"));
- c3 = layer2getc();
- if(c3==0x40) {
- LOG((" TFI request\n"));
- write(TFI_string, 6);
- }
- else {
- LOG((" TFI echo 0x%02x\n", c3));
- do {
- c3 = layer2getc();
- LOG((" TFI echo 0x%02x\n", c3));
- }
- while(c3 & 0x20); /* extension bit */
- }
- break;
-
- case 0x23:
- LOG((" define DRCS\n"));
- do_DRCS();
- break;
-
- case 0x26:
- LOG((" define color\n"));
- do_DEFCOLOR();
- break;
-
- case 0x2d: /* page 155 */
- LOG((" define Format\n"));
- do_DEFFORMAT();
- break;
-
- case 0x2f: /* page 157 */
- LOG((" Reset sequence\n"));
- do_RESET();
- alphamosaic = 1;
- break;
-
- case 0x3e: /* annex 7.4 */
- LOG((" telesoftware\n"));
- do_Telesoftware();
- alphamosaic = 0;
- break;
-
- default: /* APA active position addressing */
- if(c2<0x40) LOG((" unknown US sequence\n"));
- else {
- alphamosaic = 1;
- LOG((" new row %2d\n", c2 & 0x3f));
- c3 = layer2getc();
- LOG((" new column %2d\n", c3 & 0x3f));
- move_cursor(APA, c2 & 0x3f, c3 & 0x3f);
- t.par_attr = 0;
- t.par_fg = WHITE;
- t.par_bg = TRANSPARENT;
- }
- break;
- }
-
- /* VPDE = US x data. Each VPDE has to be followed by the next VPDE
- * immediately (page 85). The alphamosaic VPDE is introduced by APA or
- * by one of the reset functions ! Any remaining data (errors) after all
- * other VPDE's has to be skipped (*17420101711a#).
- */
- if(!alphamosaic) {
- while( (c2 = layer2getc()) != US ) LOG(("skipping to next US\n"));
- LOG(("\n"));
- layer2ungetc(US);
- }
- }
-
- void BTXService::do_ESC()
- {
- int y, c2, c3, c4;
-
- c2 = layer2getc();
-
- switch(c2) {
-
- case 0x22:
- LOG((" invoke C1\n"));
- c3 = layer2getc();
- LOG((" (%s)\n", c3==0x40 ? "serial" : "parallel"));
- if(c3==0x40) t.serialmode = 1;
- else {
- t.serialmode = 0;
- t.leftright[0] = t.save_left;
- }
- break;
-
- case 0x23:
- LOG((" set attributes\n"));
- c3 = layer2getc();
- switch(c3) {
- case 0x20:
- LOG((" full screen background\n"));
- c4 = layer2getc();
- LOG((" color = %d\n",
- c4==0x5e ? TRANSPARENT : t.clut*8+c4-0x50));
- for(y=0; y<24; y++)
- AppDisplay->define_fullrow_bg(y, c4==0x5e ?
- TRANSPARENT : t.clut*8+c4-0x50);
- break;
- case 0x21:
- LOG((" full row\n"));
- c4 = layer2getc();
- LOG((" "));
- supplementary_control_C1(c4+0x40, 1);
- break;
- }
- break;
-
- case 0x28:
-
- case 0x29:
- case 0x2a:
- case 0x2b:
- LOG((" load G%d with\n", c2 - 0x28));
- c3 = layer2getc();
- switch(c3) {
- case 0x40:
- LOG((" 'primary graphic'\n"));
- t.G0123L[c2 - 0x28] = PRIM;
- t.prim = c2 - 0x28;
- break;
- case 0x62:
- LOG((" 'supplementary graphic'\n"));
- t.G0123L[c2 - 0x28] = SUPP;
- t.supp = c2 - 0x28;
- break;
- case 0x63:
- LOG((" '2nd supplementary mosaic'\n"));
- t.G0123L[c2 - 0x28] = SUP2;
- break;
- case 0x64:
- LOG((" '3rd supplementary mosaic'\n"));
- t.G0123L[c2 - 0x28] = SUP3;
- break;
- case 0x20:
- LOG((" DRCS\n"));
- c4 = layer2getc();
- if(c4 != 0x40) LOG(("HAEH (ESC 0x%02x 0x20 0x%02x)\n", c2, c4));
- else LOG(("\n"));
- t.G0123L[c2 - 0x28] = DRCS;
- break;
- }
- break;
-
-
- case 0x6e:
- LOG((" LS2 locking shift G2 left\n"));
- t.leftright[0] = G2;
- t.save_left = G2;
- break;
-
- case 0x6f:
- LOG((" LS3 locking shift G3 left\n"));
- t.leftright[0] = G3;
- t.save_left = G3;
- break;
-
- case 0x7c:
- LOG((" LS3R locking shift G3 right\n"));
- t.leftright[1] = G3;
- break;
-
- case 0x7d:
- LOG((" LS2R locking shift G2 right\n"));
- t.leftright[1] = G2;
- break;
-
- case 0x7e:
- LOG((" LS1R locking shift G1 right\n"));
- t.leftright[1] = G1;
- break;
- }
- }
-
-
- /*
- * Process one control sequence. Return whether or not the cursor position
- * has to be advanced by one char (in case of serialmode).
- *
- * Anscheinend sollen nur die FLASH-controls den Cursor eins weiterstellen -
- * steht zwar nirgends, sieht aber am besten aus !!!
- */
-
- int BTXService::do_CSI()
- {
- int c2, c3, upper, lower;
-
- c2 = layer2getc();
- if(c2 == 0x42) {
- LOG((" STC stop conceal\n"));
- set_attr(ATTR_CONCEALED, 0, 0, t.serialmode);
- return 0;
- }
-
- LOG(("\n"));
- c3 = layer2getc();
-
- /* protection only available as fullrow controls ?? (page 135) */
- if(c2 == 0x31 && c3 == 0x50) {
- LOG((" PMS protected mode start\n"));
- set_attr(ATTR_PROTECTED, 1, 0, 2);
- return 0;
- }
- if(c2 == 0x31 && c3 == 0x51) {
- LOG((" PMC protected mode cancel\n"));
- set_attr(ATTR_PROTECTED, 0, 0, 2);
- return 0;
- }
- if(c2 == 0x32 && c3 == 0x53) {
- LOG((" MMS marked mode start\n"));
- /* set_attr(ATTR_MARKED, 1, 0, t.serialmode); */
- return 0;
- }
- if(c2 == 0x32 && c3 == 0x54) {
- LOG((" MMT marked mode stop\n"));
- /* set_attr(ATTR_MARKED, 0, 0, t.serialmode); */
- return 0;
- }
-
- switch(c3) {
-
- case 0x40:
- LOG((" invoke CLUT%d\n", c2 - 0x2f));
-
-
- t.clut = c2 - 0x30;
- return 0;
-
- case 0x41:
- switch(c2) {
- case 0x30:
- LOG((" IVF inverted flash\n"));
- return 1;
- case 0x31:
- LOG((" RIF reduced intesity flash\n"));
- return 1;
- case 0x32:
- case 0x33:
- case 0x34:
- LOG((" FF%c fast flash %c\n", c2-1, c2-1));
- return 1;
- case 0x35:
- LOG((" ICF increment flash\n"));
- return 1;
- case 0x36:
- LOG((" DCF decrement flash\n"));
- return 1;
- }
- break;
-
- case 0x60:
- switch(c2) {
- case 0x30:
- LOG((" SCU explicit scroll up\n"));
- if(t.scroll_area) scroll(1);
- return 0;
- case 0x31:
- LOG((" SCD explicit scroll down\n"));
- if(t.scroll_area) scroll(0);
-
- return 0;
- case 0x32:
- LOG((" AIS activate implicite scrolling\n"));
- t.scroll_impl = 1;
- return 0;
- case 0x33:
- LOG((" DIS deactivate implicite scrolling\n"));
- t.scroll_impl = 0;
- return 0;
- }
- break;
-
- default: /* definition of scrolling area (page 137) */
- upper = c2 & 0x0f;
- if(c3>=0x30 && c3<=0x39) upper = upper*10 + (c3&0x0f);
- LOG((" upper row: %2d\n", upper));
- if(c3>=0x30 && c3<=0x39) { c3 = layer2getc(); LOG(("\n")); }
-
- if(c3!=0x3b) ERRLOG(("XBTX: scrolling area - protocol !\n"));
-
- lower = layer2getc() & 0x0f;
- LOG(("\n"));
- c3 = layer2getc();
- if(c3>=0x30 && c3<=0x39) lower = lower*10 + (c3&0x0f);
- LOG((" lower row: %2d", lower));
- if(c3>=0x30 && c3<=0x39) { LOG(("\n")); c3=layer2getc(); LOG((" ")); }
-
- if(c3==0x55) {
- LOG((" CSA create scrolling area\n"));
- if(upper>=2 && lower<rows && lower>=upper) {
- t.scroll_upper = upper;
- t.scroll_lower = lower;
- t.scroll_area = 1;
- }
- }
- if(c3==0x56) {
- LOG((" CSD delete scrolling area\n"));
- t.scroll_area = 0;
- }
- return 0;
- }
- return 0;
- }
-
-
- void BTXService::do_DRCS() /* (page 139ff) */
- {
- int c3, c4, c5, c6, c7, c8;
-
- c3 = layer2getc();
- if(c3 == 0x20) {
- LOG((" DRCS header unit\n"));
- c4 = layer2getc();
- if(c4==0x20 || c4==0x28) {
- LOG((" %s existing DRCS\n", (c4==0x20) ? "keep" : "delete"));
-
- if(c4==0x28) AppDisplay->free_DRCS();
- c5 = layer2getc();
- } else c5 = c4;
- if(c5 == 0x20) {
- LOG(("\n"));
- c6 = layer2getc();
- } else c6 = c5;
- if(c6 == 0x40) {
- LOG(("\n"));
- c7 = layer2getc();
- } else c7 = c6;
-
- switch(c7 & 0xf) {
- case 6:
- LOG((" 12x12 pixel\n"));
- t.drcs_w = 12;
- t.drcs_h = 12;
- break;
- case 7:
- LOG((" 12x10 pixel\n"));
- t.drcs_w = 12;
- t.drcs_h = 10;
- break;
- case 10:
- LOG((" 6x12 pixel\n"));
- t.drcs_w = 6;
- t.drcs_h = 12;
- break;
- case 11:
- LOG((" 6x10 pixel\n"));
- t.drcs_w = 6;
- t.drcs_h = 10;
- break;
- case 12:
- LOG((" 6x5 pixel\n"));
- t.drcs_w = 6;
- t.drcs_h = 5;
- break;
- case 15:
- LOG((" 6x6 pixel\n"));
- t.drcs_w = 6;
- t.drcs_h = 6;
- break;
- }
-
- c8 = layer2getc();
- LOG((" %d bit/pixel\n", c8 & 0xf));
- t.drcs_bits = c8 & 0xf;
- t.drcs_step = (t.drcs_h>=10 && t.drcs_w*t.drcs_bits==24) ? 2 : 1;
- }
- else {
- LOG((" DRCS pattern transfer unit (char: 0x%02x)\n", c3));
- do_DRCS_data(c3);
- }
- }
-
-
- /*
- * load and define dynamic characters, first character is 'c'.
- * more than one bitplane of a character may be loaded simultaneously !
- */
-
- void BTXService::do_DRCS_data(int c)
- {
- int c4, i, n, planes=0, planemask=0, byte=0;
- int maxbytes, start = c;
-
- maxbytes = 2*t.drcs_h;
- if(t.drcs_h<10) maxbytes *= 2;
-
- memset(data,0,sizeof(data));
-
- do {
- c4 = layer2getc();
-
- switch(c4) {
- case 0x20: /* S-bytes */
- case 0x2f:
- LOG((" fill rest of char with %d\n", c4 & 1));
- for(; byte<maxbytes; byte++)
- for(n=0; n<4; n++)
- if(planemask & (1<<n)) data[n][byte] = (UBYTE)((c4==0x20) ? 0 : 0xff);
- break;
- case 0x21:
- case 0x22:
- case 0x23:
- case 0x24:
- case 0x25:
- case 0x26:
- case 0x27:
- case 0x28:
- case 0x29:
- case 0x2a:
- LOG((" repeat last row %d times\n", c4 & 0xf));
- if(byte&1) byte++; /* pad to full row (assume 0) */
- for(i=0; i<(c4 & 0xf); i++) {
- for(n=0; n<4; n++)
- if(planemask & (1<<n)) {
- data[n][byte] = (UBYTE)(byte ? data[n][byte-2] : 0);
- data[n][byte+1] = (UBYTE)(byte ? data[n][byte-2+1] : 0);
- if(t.drcs_h<10) {
- data[n][byte+2] = (UBYTE)(byte ? data[n][byte-2] : 0);
- data[n][byte+3] = (UBYTE)(byte ? data[n][byte-2+1] : 0);
- }
- }
- byte += 2;
- if(t.drcs_h<10) byte += 2;
- }
- break;
- case 0x2c:
- case 0x2d:
- LOG((" full row %d\n", c4 & 1));
- if(byte&1) byte++; /* pad to full row (assume 0) */
- for(n=0; n<4; n++)
- if(planemask & (1<<n)) {
- data[n][byte] = (UBYTE)((c4==0x2c) ? 0 : 0xff);
- data[n][byte+1] = (UBYTE)((c4==0x2c) ? 0 : 0xff);
- if(t.drcs_h<10) {
- data[n][byte+2] = (UBYTE)((c4==0x2c) ? 0 : 0xff);
- data[n][byte+3] = (UBYTE)((c4==0x2c) ? 0 : 0xff);
- }
- }
- byte += 2;
- if(t.drcs_h<10) byte += 2;
- break;
- case 0x2e:
- LOG((" fill rest of char with last row\n"));
- if(byte&1) byte++; /* pad to full row (assume 0) */
- while(byte<maxbytes) {
- for(n=0; n<4; n++)
- if(planemask & (1<<n)) {
- data[n][byte] = data[n][byte-2];
- data[n][byte+1] = data[n][byte-2+1];
- }
- byte += 2;
- }
- break;
-
- case 0x30: /* B-bytes */
- case 0x31:
- case 0x32:
- case 0x33:
- if(byte) {
- LOG((" new plane ahead - filling up\n"));
- byte = maxbytes; /* pad to full plane */
- layer2ungetc(c4);
- }
- else {
- LOG((" start of pattern block (plane %d)\n", c4 & 0xf));
- for(i=0; i<2*FONT_HEIGHT; i++) data[c4 & 0xf][i] = 0;
- planemask |= 1 << (c4 & 0xf);
- }
- break;
-
- default:
- if(c4<0x20 || c4>0x7f) {
- LOG((" end of pattern data\n"));
- layer2ungetc(c4);
- if(byte) byte = maxbytes;
- }
-
-
- else { /* D-bytes */
- LOG((" pattern data\n"));
- if(t.drcs_w==6) { /* low res */
- for(n=0; n<4; n++)
- if(planemask & (1<<n)) {
- data[n][byte] =
- (UBYTE)(((c4&32)?0x30:0) | ((c4&16)?0x0c:0) | ((c4&8)?0x03:0));
- data[n][byte+1] =
- (UBYTE)(((c4&4)?0x30:0) | ((c4&2)?0x0c:0) | ((c4&1)?0x03:0));
- }
- byte += 2;
- }
- else {
- for(n=0; n<4; n++)
- if(planemask & (1<<n)) data[n][byte] = (UBYTE)(c4 & 0x3f);
- byte++;
- }
-
- if(!(byte&1) && t.drcs_h<10) { /* duplicate row ? */
- for(n=0; n<4; n++)
- if(planemask & (1<<n)) {
- data[n][byte] = data[n][byte-2];
- data[n][byte+1] = data[n][byte-2+1];
- }
- byte += 2;
- }
- }
- break;
-
- } /* switch */
-
- if(byte == maxbytes) { /* plane is complete */
- for(n=0; n<4; n++) if(planemask & (1<<n)) planes++;
- planemask = 0;
- byte = 0;
- if(planes == t.drcs_bits) { /* DRC is complete */
- log_DRC(c, t.drcs_bits);
- AppDisplay->define_raw_DRC(c, &data[0][0], t.drcs_bits);
- planes = 0;
- c += t.drcs_step;
- }
- }
-
-
- } while(c4>=0x20 && c4<=0x7f);
-
- update_DRCS_display(start, c, t.drcs_step);
- }
-
-
- /*
- * pretty print the received character to the LOG file
- */
- void BTXService::log_DRC(int c, int bits)
- {
- int n, i, j, k;
-
- LOG(("\n DRC # 0x%2x\n", c));
- for(n=0; n<bits; n++) {
- LOG((" (plane %d)\n", n));
- LOG((" --------------------------\n"));
- for(j=0; j<fontheight; j++) {
- LOG((" |"));
- for(k=0; k<2; k++)
- for(i=5; i>=0; i--)
- if(data[n][j*2+k] & (1<<i)) LOG(("* "));
- else LOG((" "));
- LOG(("|\n"));
- }
- LOG((" --------------------------\n\n"));
- }
- }
-
-
- /*
- * load and define dynamic colors.
- */
- void BTXService::do_DEFCOLOR() /* (page 150ff) */
- {
- int c3, c4, c5, c6, c7, index, r, g, b;
-
- c3 = layer2getc();
-
- switch(c3) {
-
-
- case 0x20: /* US 0x26 0x20 <ICT> <SUR> <SCM> */
- LOG((" color header unit\n"));
- t.col_modmap = 1; /* by default modify colormap */
- c4 = layer2getc();
- if((c4 & 0xf0) == 0x20) {
- if(c4!=0x20 && c4!=0x22) {
- LOG(("*** <ICT>: bad value !\n"));
- ERRLOG(("XBTX: do_DEFCOLOR(): ICT1 = 0x%02x\n", c4));
- }
- LOG((" <ICT>: load %s\n", c4==0x20 ? "colormap" : "DCLUT"));
- t.col_modmap = (c4==0x20);
- c5 = layer2getc();
- } else c5 = c4;
- if((c5 & 0xf0) == 0x20) {
- LOG((" <ICT>: (unit %d)\n", c5&0xf));
- if(c5!=0x20) {
- LOG(("*** <ICT>: bad value !\n"));
- ERRLOG(("XBTX: do_DEFCOLOR(): ICT2 = 0x%02x\n", c5));
- }
- c6 = layer2getc();
- } else c6 = c5;
- if((c6 & 0xf0) == 0x30) {
- LOG((" <SUR>: %d bits\n", c6&0xf));
- if(c6!=0x34 && c6!=0x35) {
- LOG(("*** <SUR>: bad value !\n"));
- ERRLOG(("XBTX: do_DEFCOLOR(): SUR = 0x%02x\n", c6));
- }
- c7 = layer2getc();
- } else c7 = c6;
- if((c7 & 0xf0) == 0x40) {
- LOG((" <SCM>: 0x%02x\n", c7));
- if(c7!=0x40 && c7!=0x41) {
- LOG(("*** <SCM>: bad value !\n"));
- ERRLOG(("XBTX: do_DEFCOLOR(): SCM = 0x%02x\n", c7));
- }
- } else {
- LOG((" default header\n"));
- layer2ungetc(c7);
- }
- break;
-
- case 0x21:
- LOG((" color reset unit\n"));
- AppDisplay->default_colors();
- break;
-
- default:
- LOG((" color transfer unit (1.Stelle: %d)\n", c3&0xf));
- index = c3&0xf;
- c4 = layer2getc();
- if((c4 & 0xf0) == 0x30) { /* c3 zehner, c4 einer */
- LOG((" (2.Stelle: %d)\n", c4&0xf));
- index = (c3&0xf)*10 + (c4&0xf);
- c5 = layer2getc();
- } else c5 = c4;
-
- if(t.col_modmap) { /* load colormap */
- while(c5>=0x40 && c5<=0x7f) {
- LOG((" color #%2d: R G B\n", index));
- c6 = layer2getc();
- r = (c5&0x20)>>2 | (c5&0x04) | (c6&0x20)>>4 | (c6&0x04)>>2;
- g = (c5&0x10)>>1 | (c5&0x02)<<1 | (c6&0x10)>>3 | (c6&0x02)>>1;
- b = (c5&0x08) | (c5&0x01)<<2 | (c6&0x08)>>2 | (c6&0x01);
-
- LOG((" %1x %1x %1x\n", r, g, b));
- if(index>=16 && index<=31) AppDisplay->define_color(index++, r, g, b);
- c5 = layer2getc();
- }
- }
- else { /* load DCLUT */
- while(c5>=0x40 && c5<=0x7f) {
- LOG((" DCLUT[%2d] = %2d\n", index, c5&0x1f));
- if(index>=0 && index<=3) AppDisplay->define_DCLUT(index++, c5&0x1f);
- c5 = layer2getc();
- }
- }
-
- LOG((" end of color data\n"));
- layer2ungetc(c5);
- break;
- }
- }
-
-
- void BTXService::do_DEFFORMAT() /* format designation (page 155) */
- {
- int c3, c4;
-
- rows = 24;
- fontheight = 10;
- t.wrap = 1;
-
- c3 = layer2getc();
- if((c3&0xf0) == 0x40) {
- switch(c3) {
- case 0x41:
- LOG((" 40 columns by 24 rows\n"));
- break;
- case 0x42:
- LOG((" 40 columns by 20 rows\n"));
- rows = 20;
- fontheight = 12;
- break;
- default:
- LOG((" unrecognized format (using default)\n"));
- break;
- }
- c4 = layer2getc();
- }
- else c4 = c3;
-
- if((c4&0xf0) == 0x70) {
- LOG((" wraparound %s\n", (c3&1) ? "inactive" : "active"));
- t.wrap = (c3 == 0x70) ? 1 : 0;
- }
- else {
- LOG((" default format\n"));
- layer2ungetc(c4);
- }
- }
-
-
- void BTXService::do_RESET() /* reset functions (page 157) */
- {
- int y, c3, c4;
-
- c3 = layer2getc();
-
- switch(c3) {
-
- case 0x40: /* (page 158) */
- LOG((" service break to row\n"));
- c4 = layer2getc();
- LOG((" #%d\n", c4 & 0x3f));
- backup = t; /* structure copy */
- t.leftright[0] = t.prim; /* PFUSCH !!! */
- t.leftright[1] = t.supp;
- t.save_left = t.prim;
- t.wrap = 0;
- t.cursor_on = 0;
- move_cursor(APA, c4 & 0x3f, 1);
- t.serialmode = 1;
- t.clut = 0;
- t.service_break = 1;
- break;
-
- case 0x41:
- case 0x42:
- LOG((" defaults (%s C1)\n", c3&1 ? "serial" : "parallel"));
- default_sets();
- t.serialmode = c3 & 1;
- t.wrap = 1;
- t.cursor_on = 0;
- rows = 24;
- fontheight = 10;
- for(y=0; y<24; y++) AppDisplay->define_fullrow_bg(y, BLACK);
- clearscreen(); /* clearscr resets CLUT, par_attr, cursor pos */
- break;
-
- case 0x43:
- case 0x44:
- LOG((" limited defaults (%s C1)\n", c3&1 ? "serial":"parallel"));
- default_sets();
- t.serialmode = c3 & 1;
- break;
-
- case 0x4f:
- LOG((" reset to previous state\n"));
- t = backup;
- move_cursor(APA, t.cursory, t.cursorx);
- break;
- }
- }
-
-
- /*
- * set/reset parallel, serial or fullrow attributes (+ set/delete markers)
- * (mode: 0=parallel, 1=serial, 2=fullrow)
- *
- * MARKER: (page 91 / annex 1, page 29)
- *
- * parallel: (set in output())
- * set wherever an attr is changed
- * set at attr changes in writing a continuous string
- * delete existing markers in overwritten part of "
- * delete when printing and attrs do not change
- *
- * serial: (set here)
- * set at this position
- */
-
- void BTXService::set_attr(int a, int set, int col, int mode)
- {
- int x, y = t.cursory-1, refresh, mattr = a;
-
- /* set fullrow background */
- if(mode==2 && a==ATTR_BACKGROUND) {
- AppDisplay->define_fullrow_bg(y, col);
- return;
- }
-
- if(a & ATTR_ANYSIZE) mattr = ATTR_SIZE;
-
- /* serial mode controls set a marker */
- if(mode==1) screen[y][t.cursorx-1].mark |= mattr;
-
- /* serial/fullrow controls apply to parts of the row */
- if(mode) { /* serial || fullrow */
-
- /* receiption of serial DBS/DBH in last row of scrolling area */
- /* forces a scroll up + a cursor up before writing (page 101) */
- if( (t.service_break || !(screen[y][0].attr & ATTR_PROTECTED)) &&
- (a==ATTR_YDOUBLE || a==ATTR_XYDOUBLE) &&
- t.scroll_area && t.cursory==t.scroll_lower) {
- scroll(1);
- move_cursor(APU);
- y = t.cursory-1;
- }
-
- x = (mode==2) ? 0 : t.cursorx-1;
-
- do {
- refresh = 0;
-
- /* fullrow controls delete the marker in the complete row */
- if(mode==2) screen[y][x].mark &= ~mattr;
-
- if( t.service_break || !(screen[y][x].attr & ATTR_PROTECTED) ||
- (a==ATTR_PROTECTED && set==0) ) {
- switch(a) {
- case ATTR_NODOUBLE:
- if(screen[y][x].attr & (ATTR_XDOUBLE|ATTR_YDOUBLE))
- refresh = 1;
- screen[y][x].attr &= ~(ATTR_XDOUBLE|ATTR_YDOUBLE);
- break;
- case ATTR_XYDOUBLE:
- if((screen[y][x].attr & (ATTR_XDOUBLE|ATTR_YDOUBLE)) !=
- (ATTR_XDOUBLE|ATTR_YDOUBLE) ) refresh = 1;
- screen[y][x].attr |= (ATTR_XDOUBLE|ATTR_YDOUBLE);
- break;
- case ATTR_XDOUBLE:
- if((screen[y][x].attr & (ATTR_XDOUBLE|ATTR_YDOUBLE)) !=
- ATTR_XDOUBLE ) refresh = 1;
- screen[y][x].attr &= ~ATTR_YDOUBLE;
- screen[y][x].attr |= ATTR_XDOUBLE;
- break;
- case ATTR_YDOUBLE:
- if((screen[y][x].attr & (ATTR_XDOUBLE|ATTR_YDOUBLE)) !=
- ATTR_YDOUBLE ) refresh = 1;
- screen[y][x].attr &= ~ATTR_XDOUBLE;
- screen[y][x].attr |= ATTR_YDOUBLE;
- break;
- case ATTR_FOREGROUND:
- if(screen[y][x].fg!=col && screen[y][x].chr!=' ') refresh=1;
- screen[y][x].fg = (UBYTE)col;
- break;
- case ATTR_BACKGROUND:
- if(screen[y][x].bg != col) refresh = 1;
- screen[y][x].bg = (UBYTE)col;
- break;
-
- default:
- if( ((screen[y][x].attr & a)>0) != set ) refresh = 1;
- if(set) screen[y][x].attr |= a;
- else screen[y][x].attr &= ~a;
- break;
- } /* switch */
-
- if(refresh) redrawc(x+1, y+1);
-
- /* (DBH/DBS chars must not cross borders of a protected area) */
- if(a==ATTR_PROTECTED && y && realattr(y, x+1, ATTR_YDOUBLE) &&
- attrib(y, x+1, a) != attrib(y+1, x+1, a) ) redrawc(x+1, y);
-
- } /* if !protected */
-
- x++;
- } /* while x<40 && (serialmode --> no marker set) */
- while(x<40 && (mode!=1 || !(screen[y][x].mark & mattr)) );
- }
- else { /* parallel */
- switch(a) {
- case ATTR_NODOUBLE:
- t.par_attr &= ~(ATTR_XDOUBLE|ATTR_YDOUBLE);
- break;
- case ATTR_XYDOUBLE:
- t.par_attr |= (ATTR_XDOUBLE|ATTR_YDOUBLE);
- break;
- case ATTR_XDOUBLE:
- t.par_attr &= ~ATTR_YDOUBLE;
- t.par_attr |= ATTR_XDOUBLE;
- break;
- case ATTR_YDOUBLE:
- t.par_attr &= ~ATTR_XDOUBLE;
- t.par_attr |= ATTR_YDOUBLE;
- break;
- case ATTR_FOREGROUND:
- t.par_fg = col;
- break;
- case ATTR_BACKGROUND:
- t.par_bg = col;
- break;
- default:
- if(set) t.par_attr |= a;
- else t.par_attr &= ~a;
- break;
- }
- }
- }
-
-
- /*
- * output character c from current set at current cursor position.
- */
-
- void BTXService::output(int c)
- {
- int xd, yd, set, mattr, x = t.cursorx, y = t.cursory;
-
- /* select active character set */
- if(t.sshift) set = t.G0123L[ t.sshift ];
- else set = t.G0123L[ t.leftright[ (c&0x80) >> 7 ] ];
-
- if(t.serialmode) {
- xd = attrib(y, x, ATTR_XDOUBLE);
- yd = attrib(y, x, ATTR_YDOUBLE);
-
- /* update screen memory (if not protected) */
- if( t.service_break || !attrib(y, x, ATTR_PROTECTED) ) {
- screen[y-1][x-1].chr = (unsigned short)(c & ~0x80);
- screen[y-1][x-1].set = (UBYTE)set;
- redrawc(x, y);
- }
- }
- else { /* parallel */
- xd = (t.par_attr & ATTR_XDOUBLE) > 0;
- yd = (t.par_attr & ATTR_YDOUBLE) > 0;
- if(y<2) yd = 0;
-
- /* if not protected, (scroll +) update memory */
- if( t.service_break || !attrib(y, x, ATTR_PROTECTED) ) {
-
-
-
- /* parallel DBS/DBH chars in first row of scrolling area */
- /* force a scroll down + a cursor down before writing (page 101) */
- if(yd && t.scroll_area && y==t.scroll_upper) {
- scroll(0);
- move_cursor(APD);
- y = t.cursory;
- }
-
- /* update screen memory
- * if no DBS/DBH in the first row or in the row below a protected area
- * if no DBS/DBH in the row below a scrolling area (page 99)
- */
- if( !(yd && !t.service_break && attrib(y-1, x, ATTR_PROTECTED)) &&
- !(yd && t.scroll_area && y==t.scroll_lower+1) ) {
-
- /* parallel DBH/DBS chars extent upwards, write in the row above */
- if(yd) y--;
-
- screen[y-1][x-1].chr = (unsigned short)(c & ~0x80);
- screen[y-1][x-1].set = (UBYTE)set;
- screen[y-1][x-1].fg = (UBYTE)t.par_fg;
- screen[y-1][x-1].bg = (UBYTE)t.par_bg;
- screen[y-1][x-1].attr = (unsigned short)t.par_attr;
-
- /* par. DBS/DBW attrs apply also to the next char ! (page 106) */
- if(xd && x<40) screen[y-1][x].attr = (unsigned short)t.par_attr;
-
- mattr = t.par_attr & ~ATTR_ANYSIZE;
- if(t.par_attr & ATTR_ANYSIZE) mattr |= ATTR_SIZE;
-
- if(x>1) { /* set/reset markers */
- screen[y-1][x-1].mark = (unsigned short)(screen[y-1][x-1-1].attr ^ mattr);
- screen[y-1][x-1].mark &= ~(ATTR_FOREGROUND|ATTR_BACKGROUND);
- if(screen[y-1][x-1-1].fg!=t.par_fg)
- screen[y-1][x-1].mark |= ATTR_FOREGROUND;
- if(screen[y-1][x-1-1].bg!=t.par_bg)
- screen[y-1][x-1].mark |= ATTR_BACKGROUND;
- }
- if(x<40) { /* set/reset markers */
- screen[y-1][x].mark = (unsigned short)(mattr ^ screen[y-1][x].attr);
- screen[y-1][x].mark &= ~(ATTR_FOREGROUND|ATTR_BACKGROUND);
- if(screen[y-1][x].fg!=t.par_fg)
- screen[y-1][x].mark |= ATTR_FOREGROUND;
- if(screen[y-1][x].bg!=t.par_bg)
- screen[y-1][x].mark |= ATTR_BACKGROUND;
- }
-
- redrawc(x, y);
- } /* scrolling/protected area */
- } /* if not protected */
- } /* if serial / parallel */
-
- if(xd && t.cursorx<40) move_cursor(APF);
- move_cursor(APF);
- t.sshift = 0;
- }
-
-
- /*
- * redraws character at screen position x, y (1 based !),
- * if not concealed or obscured
- */
-
- void BTXService::redrawc(int x, int y)
- {
- // extern int reveal;
- int c, set, xd, yd, up_in=0, dn_in=0;
- unsigned int real, xreal, yreal, xyreal;
-
- /* check whether attributes are valid */
- xd = attrib(y, x, ATTR_XDOUBLE);
- yd = attrib(y, x, ATTR_YDOUBLE);
- if(x>=40) xd = 0;
- if(y>=rows) yd = 0;
-
- /* check whether origin is obscured */
- if( (y>1 && realattr(y-1, x, ATTR_YDOUBLE)) ||
- (x>1 && realattr(y, x-1, ATTR_XDOUBLE)) ||
- (y>1 && x>1 && realattr(y-1, x-1, ATTR_XDOUBLE) &&
- realattr(y-1, x-1, ATTR_YDOUBLE)) ) {
- screen[y-1][x-1].real = 0;
- }
- else {
- /* check whether DBW char is partially obscured */
- if(xd && y>1 && x<40 && realattr(y-1, x+1, ATTR_YDOUBLE)) xd = 0;
-
- /* check whether char crosses borders of scrolling area (page 99) */
- if(yd && t.scroll_area) {
- if(y >=t.scroll_upper && y <=t.scroll_lower) up_in=1;
- if(y+1>=t.scroll_upper && y+1<=t.scroll_lower) dn_in=1;
- if(up_in != dn_in) yd = 0;
- }
-
- /* check whether char crosses borders of protected area (page 110) */
- if(yd && attrib(y, x, ATTR_PROTECTED) !=
- attrib(y+1, x, ATTR_PROTECTED) ) yd=0;
-
- /* concealed characters are drawn as SPACES (page 109) */
- // if(!reveal && attrib(y, x, ATTR_CONCEALED)) { c=' '; set=PRIM; }
- // else {
- c = screen[y-1][x-1].chr & 0x7f;
- set = screen[y-1][x-1].set;
- // }
-
- /* now really display the character in the remaining size */
- AppDisplay->xputc(c, set, x-1, y-1, xd, yd,
- attrib(y, x, ATTR_UNDERLINE),
- (screen[y-1][x-1].chr>>8) & 0x7f,
- attrib(y, x, ATTR_INVERTED) ? attr_bg(y, x) : attr_fg(y, x),
- attrib(y, x, ATTR_INVERTED) ? attr_fg(y, x) : attr_bg(y, x) );
- if(t.cursor_on && x==t.cursorx && y==t.cursory) AppDisplay->xcursor(x-1, y-1);
-
- /* update 'real' attributes */
- real = screen[y-1][x-1].real;
- screen[y-1][x-1].real = (unsigned short)(screen[y-1][x-1].attr & ~ATTR_ANYSIZE);
- if(xd) {
- screen[y-1][x-1].real |= ATTR_XDOUBLE;
- xreal = screen[y-1][x].real;
- screen[y-1][x].real = 0;
- }
- if(yd) {
- screen[y-1][x-1].real |= ATTR_YDOUBLE;
- yreal = screen[y][x-1].real;
- screen[y][x-1].real = 0;
- }
- if(xd && yd) {
- xyreal = screen[y][x].real;
- screen[y][x].real = 0;
- }
-
- /* redraw (indirect recursion !!) neighbours */
- updatec(real, x, y);
- if(xd) updatec(xreal, x+1, y);
- if(yd) updatec(yreal, x, y+1);
- if(xd && yd) updatec(xyreal, x+1, y+1);
-
- /* redraw an enlarged char to the left (now partially obscured !) */
- if(yd && x>1 && realattr(y+1, x-1, ATTR_XDOUBLE)) redrawc(x-1, y+1);
- } /* origin obscured */
- }
-
-
- /*
- * this character has been obscured. check whether it was an enlarged char
- * and therefor its neighbours have to be redrawn.
- */
- void BTXService::updatec(int real, int x, int y)
- {
- if(real & ATTR_XDOUBLE) redrawc(x+1, y);
- if(real & ATTR_YDOUBLE) redrawc(x, y+1);
- if( (real & ATTR_XDOUBLE) && (real & ATTR_YDOUBLE) ) redrawc(x+1, y+1);
- }
-
-
- /*
- * redraw rectangle of screen (for exposure handling)
- */
-
-
- void BTXService::redraw_screen_rect(int x1, int y1, int x2, int y2)
- {
- int x, y;
-
- for(y=y1; y<=y2; y++)
- for(x=x1; x<=x2; x++) redrawc(x+1, y+1);
- }
-
-
- /*
- * DRC's in the range start-stop with step have been (re)defined.
- * This routine checks whether this character is currently visible and so
- * needs to be redisplayed.
- */
-
- void BTXService::update_DRCS_display(int start, int stop, int step)
- {
- int x, y, c;
-
- for(y=0; y<24; y++)
- for(x=0; x<40; x++)
- if(screen[y][x].set==DRCS)
- for(c=start; c<stop; c+=step)
- if(screen[y][x].chr==c) redrawc(x+1, y+1);
- }
-
-
- /*
- * initialize screen memory and clear display
- */
-
- void BTXService::clearscreen()
- {
- int x, y;
-
- t.clut = 0;
- t.par_attr = 0;
- t.par_fg = WHITE;
- t.par_bg = TRANSPARENT;
- t.scroll_area = 0;
- t.scroll_impl = 1;
- t.cursorx = t.cursory = 1;
-
- for(y=0; y<24; y++)
- for(x=0; x<40; x++) {
- screen[y][x].chr = ' ';
- screen[y][x].set = PRIM;
- screen[y][x].attr = 0;
- screen[y][x].real = 0;
- screen[y][x].mark = 0;
- screen[y][x].fg = WHITE;
- screen[y][x].bg = TRANSPARENT;
- }
-
- AppDisplay->xclearscreen();
- if(t.cursor_on) AppDisplay->xcursor(0, 0);
- }
-
- void BTXService::scroll(int up)
- {
- int y, x, savereal[40];
-
- if(up) {
- /* save real attributes of first row */
- for(x=0; x<40; x++) savereal[x] = screen[t.scroll_upper-1][x].real;
-
- /* scroll screen memory up */
- for(y=t.scroll_upper-1; y<t.scroll_lower-1; y++) {
- for(x=0; x<40; x++) screen[y][x] = screen[y+1][x];
- }
- }
- else {
- /* scroll screen memory down */
- for(y=t.scroll_lower-1; y>t.scroll_upper-1; y--) {
- for(x=0; x<40; x++) screen[y][x] = screen[y-1][x];
- }
- }
-
- /* clear row */
- for(x=0; x<40; x++) {
- screen[y][x].chr = ' ';
- screen[y][x].set = PRIM;
- screen[y][x].attr = 0;
- screen[y][x].real = 0;
- screen[y][x].mark = 0;
- screen[y][x].fg = WHITE;
- screen[y][x].bg = TRANSPARENT;
- }
-
- /* fast scroll the area */
- for(y=t.scroll_upper; y<=t.scroll_lower; y++)
- for(x=1; x<=40; x++) redrawc(x, y);
-
- /* redraw cursor */
- if(t.cursor_on && t.cursory>=t.scroll_upper && t.cursory<=t.scroll_lower)
- AppDisplay->xcursor(t.cursorx-1, t.cursory-1);
- }
-
- void BTXService::do_Telesoftware(void)
- {
- int c,i,j,len,total,size,temp;
- UBYTE *data,*final;
-
- c = layer2getc();
-
- if(reachedEOF)
- return;
-
- switch(c)
- {
- case 0x27: // D-Set mode, A7.4, p5
-
- for(i = 0 ; i < 4 ; i++)
- layer2getc();
-
- c = layer2getc();
-
- if(reachedEOF)
- return;
-
- telemode = MODE_Unknown;
-
- if(c == 0x42)
- telemode = MODE_3in4;
-
- if(c == 0x41)
- telemode = MODE_8Bit;
-
- telesequence = 0x41;
-
- LOG(("d-set mode, mode = %ld\n",telemode));
-
- break;
-
- case 0x33: // D-End group, A7.4, p6
-
- LOG(("d-end group\n"));
-
- if(telefile)
- {
- fclose(telefile);
- telefile = NULL;
- }
-
- telemode = MODE_Unknown;
-
- teledownload = FALSE;
-
- telename[0] = 0;
-
- break;
-
- default: // D-Data, A7.4, p3
-
- telesequence = c;
-
- LOG(("sequence code 0x%02lx\n",c));
-
- if(telemode != MODE_3in4) // Hier ist nur 3in4 zugelassen
- break;
-
- total = 0;
-
- for(;;)
- {
- c = layer2getc();
-
- if(reachedEOF)
- return;
- else
- {
- if(c == US)
- {
- layer2ungetc(c);
- break;
- }
- else
- telebuffer[total++] = (UBYTE)c;
- }
- }
-
- len = decode_3in4(telebuffer,telebuffer,total);
- data = telebuffer;
-
- while(len > 0)
- {
- switch(*data)
- {
- case 0x23: // T-Associate, A7.4, p7
-
- len--;
- data++;
-
- LOG(("t-associate\n"));
-
- teledownload = TRUE;
-
- len--;
- size = *data++;
-
- len -= size;
- data += size;
-
- break;
-
- case 0x63: // T-Filespec, A7.4, p9
-
- len--;
- data++;
-
- LOG(("t-filespec\n"));
-
- len--;
- size = *data++;
- final = data + size;
- len -= size;
-
- data++;
- size--;
-
- while(size > 0)
- {
- c = *data++;
- size--;
-
- switch(c)
- {
- case 0x65: // Filename
-
- total = *data++;
- size--;
-
- for(j = 0 ; j < total ; j++)
- {
- telename[j] = (char)*data++;
- size--;
- }
-
- telename[j] = 0;
-
- LOG(("filename |%s|\n",telename));
-
- break;
-
- case 0x7F: // Date/time
-
- total = *data++;
- size--;
-
- for(j = 0 ; j < total ; j++)
- {
- teledate[j] = (char)*data++;
- size--;
- }
-
- teledate[j] = 0;
-
- LOG(("date |%s|\n",teledate));
-
- break;
-
- case 0x67: // File length
-
- total = *data++;
- size--;
-
- temp = 0;
-
- for(j = 0 ; j < total ; j++)
- {
- temp = (temp * 256) + (*data++);
- size--;
- }
-
- telesize = temp;
-
- LOG(("size %ld\n",temp));
-
- break;
-
- default: // Was auch immer...
-
- total = *data++;
- size--;
-
- data += total;
- size -= total;
- break;
- }
- }
-
- data = final;
-
- break;
-
- case 0x43: // T-Write-Start, A7.4, p10
-
- len--;
- data++;
-
- LOG(("t-write-start\n"));
-
- len--;
- size = *data++;
-
- len -= size;
- data += size;
-
- if(telefile)
- {
- fclose(telefile);
- telefile = NULL;
- }
-
- if(!telefile && teledownload)
- {
- if(telename[0])
- telefile = fopen((const char *)telename,"wb");
- else
- telefile = fopen((const char *)"telesoftware","wb");
- }
-
- if(len)
- {
- LOG(("\t%ld bytes in this block\n",len));
-
- if(telefile)
- {
- if(fwrite(data,len,1,telefile) != 1)
- return;
- }
-
- len = 0;
- }
-
- break;
-
- case 0x45: // T-Write, A7.4, p11
-
- len--;
- data++;
-
- LOG(("t-write\n"));
-
- len--;
- size = *data++;
-
- len -= size;
- data += size;
-
- if(len)
- {
- LOG(("\t%ld bytes in this block\n",len));
-
- if(telefile)
- {
- if(fwrite(data,len,1,telefile) != 1)
- return;
- }
-
- len = 0;
- }
-
- break;
-
- case 0x47: // T-Write-End, A7.4, p11
-
- len--;
- data++;
-
- LOG(("t-write-end\n"));
-
- len--;
- size = *data++;
-
- len -= size;
- data += size;
-
- if(len)
- {
- LOG(("\t%ld bytes in this block\n",len));
-
- if(telefile)
- {
- if(fwrite(data,len,1,telefile) != 1)
- return;
- }
-
-
- len = 0;
- }
-
- if(telefile)
- {
- fclose(telefile);
- telefile = NULL;
- }
-
- break;
-
- default:
-
- LOG(("unknown sequence 0x%02lx\n",c));
-
- len--;
- data++;
-
- len--;
- size = *data++;
-
- len -= size;
- data += size;
-
- break;
- }
- }
-
- break;
- }
- }
-
- void BTXService::write(const UBYTE *what,int len)
- {
- App->AppChannel->PutString((CONST STRPTR)what,len);
- }
-
- int BTXService::decode_3in4(const UBYTE *data,UBYTE *out,int total)
- {
- UBYTE buf[4];
- int len,eaten,done = 0;
-
- while(total > 0)
- {
- if(total == 2)
- {
- buf[0] = (UBYTE)(((data[0] & 0x30) << 2) | (data[1] & 0x3f));
- len = 1;
- eaten = 2;
- }
- else
- {
- if(total == 3)
- {
- buf[0] = (UBYTE)(((data[0] & 0x30) << 2) | (data[1] & 0x3f));
- buf[1] = (UBYTE)(((data[0] & 0x0c) << 4) | (data[2] & 0x3f));
- len = 2;
- eaten = 3;
- }
- else
- {
- if(total >= 4)
- {
- buf[0] = (UBYTE)(((data[0] & 0x30) << 2) | (data[1] & 0x3f));
- buf[1] = (UBYTE)(((data[0] & 0x0c) << 4) | (data[2] & 0x3f));
- buf[2] = (UBYTE)(((data[0] & 0x03) << 6) | (data[3] & 0x3f));
- len = 3;
- eaten = 4;
- }
- else
- break;
- }
- }
-
- memcpy(out,buf,len);
-
- total -= eaten;
- data += eaten;
-
- out += len;
- done += len;
- }
-
- return(done);
- }
-